package com.company.project.configurer;

import com.company.project.core.Result;
import com.company.project.core.ResultGenerator;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.MessageFormat;

/**
 * 统一异常处理
 * @author Li
 */
@ControllerAdvice
public class HandlerException {

    /**
     * 拦截缺少参数的异常
     * @param ex
     * @param response
     * @return
     * @throws MissingServletRequestParameterException
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public Result processMethod(MissingServletRequestParameterException ex, HttpServletResponse response) throws IOException {
        String message = "{0}:[{1}]:{2}";
        message = MessageFormat.format(message, AbnormalErrorEnum.VALID.getAbnormal(),  ex.getParameterName(),"参数为必填项");
        ex.printStackTrace();
        return ResultGenerator.genFailResult(message);
    }

    /**
     * 不合法参数
     * IllegalArgumentException
     * @param ex
     * @return json格式类型
     */
    @ExceptionHandler({IllegalArgumentException.class}) //指定拦截异常的类型
    @ResponseStatus(HttpStatus.OK)  //自定义浏览器返回状态码
    @ResponseBody
    public Result customExceptionHandler(IllegalArgumentException ex) {
        String message = "{0}:{1}";
        message = MessageFormat.format(message,AbnormalErrorEnum.VALID.getAbnormal(), ex.getMessage());
        ex.printStackTrace();
        return ResultGenerator.genFailResult(message);
    }

    /**
     * 处理参数绑定异常
     * @param ex
     * @param response
     * @return
     * @throws BindException
     */
    @ExceptionHandler(BindException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public Result processMethod(BindException ex, HttpServletResponse response) throws IOException {
        FieldError fieldError = ex.getBindingResult().getFieldError();
        String message = "{0}:[{1}]:{2}";
        message = MessageFormat.format(message, AbnormalErrorEnum.VALID.getAbnormal(), fieldError.getField(),fieldError.getDefaultMessage());
        ex.printStackTrace();
        return ResultGenerator.genFailResult(message);
    }

    /**
     * io异常
     * @param ex
     * @param response
     * @return
     * @throws BindException
     */
    @ExceptionHandler(IOException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public Result processMethod(IOException ex, HttpServletResponse response) throws IOException {
        String message = "{0}:{1}";
        message = MessageFormat.format(message, AbnormalErrorEnum.IMPLEMENT.getAbnormal(), ex.getMessage());
        ex.printStackTrace();
        return ResultGenerator.genFailResult(message);
    }

    /**
     * 接口不存在异常
     * @param ex
     * @param response
     * @return
     * @throws BindException
     */
    @ExceptionHandler(NoHandlerFoundException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public Result processMethod(NoHandlerFoundException ex, HttpServletResponse response) throws IOException {
        String message = "{0}:{1}";
        message = MessageFormat.format(message,AbnormalErrorEnum.IMPLEMENT.getAbnormal(), ex.getMessage());
        ex.printStackTrace();
        return ResultGenerator.genFailResult(message);
    }

    /**
     * 业务异常
     * @param ex
     * @param response
     * @return
     * @throws BindException
     */
    @ExceptionHandler(ServletException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public Result processMethod(ServletException ex, HttpServletResponse response) throws IOException {
        String message = "{0}:{1}";
        message = MessageFormat.format(message, AbnormalErrorEnum.IMPLEMENT.getAbnormal(), ex.getMessage());
        ex.printStackTrace();
        return ResultGenerator.genFailResult(message);
    }

    /**
     * 总异常
     * @param ex
     * @param response
     * @return
     * @throws BindException
     */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public Result processMethod(Exception ex, HttpServletResponse response) throws IOException {

        String message = "{0}:{1}";
        message = MessageFormat.format(message, AbnormalErrorEnum.SYSTEM.getAbnormal(), ex.getMessage());
        //result.setCode(ResultCode.INTERNAL_SERVER_ERROR).setMessage("接口 [" + request.getRequestURI() + "] 内部错误，请联系管理员");
        ex.printStackTrace();
        return ResultGenerator.genFailResult(message);
    }
}
